package com.my.zl.console.service.online.impl;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.my.zl.common.dto.ReqDTO;
import com.my.zl.common.dto.advancedQuery.PageQueryDTO;
import com.my.zl.common.enums.resp.GlobalEnum;
import com.my.zl.common.exception.BizException;
import com.my.zl.common.utils.CopyUtil;
import com.my.zl.console.common.constant.AutocodeC;
import com.my.zl.console.dao.online.ZlDatabaseInfoMapper;
import com.my.zl.console.dao.online.ZlDatabaseSqlMapper;
import com.my.zl.console.dao.online.ZlDatabaseTableMapper;
import com.my.zl.console.dto.online.databaseInfo.ReqDatabaseInfoAddDTO;
import com.my.zl.console.dto.online.databaseInfo.ReqDatabaseInfoDelDTO;
import com.my.zl.console.dto.online.databaseInfo.ReqDatabaseInfoDetailDTO;
import com.my.zl.console.dto.online.databaseInfo.ReqDatabaseInfoEditDTO;
import com.my.zl.console.dto.online.databaseInfo.ReqDatabaseInfoQueryDTO;
import com.my.zl.console.dto.online.databaseInfo.ReqDatabaseInfoStateDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoAddDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoDelDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoDetailDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoEditDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoQueryDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoStateDTO;
import com.my.zl.console.dto.online.databaseInfo.ResDatabaseInfoVO2;
import com.my.zl.console.entity.online.ZlDatabaseInfo;
import com.my.zl.console.po.online.ZlDatabaseInfoVo;
import com.my.zl.console.service.base.BaseManager;
import com.my.zl.console.service.online.IDatabaseInfoService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.db.ds.simple.SimpleDataSource;

import org.apache.commons.lang.StringUtils;

/**
 * 数据库配置
 * @author ZL
 */
@Service
public class DatabaseInfoServiceImpl extends BaseManager implements IDatabaseInfoService {

    @Autowired
    private ZlDatabaseInfoMapper databaseInfoMapper;
    @Autowired
    private ZlDatabaseSqlMapper databaseSqlMapper;
    @Autowired
    private ZlDatabaseTableMapper databaseTableMapper;
    @Autowired
    protected DataSource dynamicDataSource;
    
    @Override
    public ResDatabaseInfoQueryDTO queryDatabaseInfoList(ReqDatabaseInfoQueryDTO reqInfo,PageQueryDTO page) throws Exception{
        // TODO Auto-generated method stub
        ResDatabaseInfoQueryDTO resDTO = BeanUtil.copyProperties(page, ResDatabaseInfoQueryDTO.class);
        
        if(!"1".equals(reqInfo.getQuerySourceType()) &&StringUtils.isNotBlank(reqInfo.getDatabaseTitle())){
            reqInfo.setDatabaseTitle("%"+reqInfo.getDatabaseTitle()+"%");
        }
        
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqInfo);
        
        pageHandle(page);//处理分页数据
        //当效率不行时自行计数，或完全自行分页，先查询总数，如果为0不用再次查询了；开启计数：true是,false否
        //临近第一条SQL查询语句自动分页,如果未消费时(即后面没有触发SQL查询)则需主动调用pageHp.clear()清理
        Page<Object> pageHp = PageHelper.startPage(page.getPage(), page.getLimit(),page.getSortorder());
        List<ZlDatabaseInfoVo> list = databaseInfoMapper.selectListPage(paramMap);
        resDTO.setData(CopyUtil.copyList(list, ResDatabaseInfoVO2.class));
        resDTO.setCount(pageHp.getTotal());
        
        return resDTO;
    }
    
    @Override
    public ResDatabaseInfoDetailDTO queryDatabaseInfoDetail(ReqDatabaseInfoDetailDTO reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ResDatabaseInfoDetailDTO res = new ResDatabaseInfoDetailDTO();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqInfo);
        ZlDatabaseInfo view = databaseInfoMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(view, res);
        return res;
    }
    
    @Override
    public ResDatabaseInfoAddDTO insertDatabaseInfoInfo(ReqDTO<ReqDatabaseInfoAddDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqDatabaseInfoAddDTO reqData = reqInfo.getReqData();
        ResDatabaseInfoAddDTO res = new ResDatabaseInfoAddDTO();
        Instant time = getSystemTime().getUtcTime();
        
        ZlDatabaseInfo record = new ZlDatabaseInfo();
        BeanUtil.copyProperties(reqData, record);
        
        initCreateInfo(record, reqInfo, time);
        record.setDatabaseId(IdUtil.simpleUUID());
        record.setDataStatus(AutocodeC.DataStatus.ENABLE.getCode());//状态
        
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("databaseId",record.getDatabaseId());
        //检查主键是否冲突
        if(databaseInfoMapper.countExistKey(paramMap)>0){
            throw new BizException(GlobalEnum.DUPLICATE_PRIMARY_KEY);
        }
        
        databaseInfoMapper.insertSelective(record);
        
        ZlDatabaseInfo keyInfo = databaseInfoMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResDatabaseInfoEditDTO updateDatabaseInfoInfo(ReqDTO<ReqDatabaseInfoEditDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqDatabaseInfoEditDTO reqData = reqInfo.getReqData();
        ResDatabaseInfoEditDTO res = new ResDatabaseInfoEditDTO();
        Instant time = getSystemTime().getUtcTime();
        
        ZlDatabaseInfo record = new ZlDatabaseInfo();
        BeanUtil.copyProperties(reqData, record);
        
        initUpdateInfo(record, reqInfo, time);
        
        databaseInfoMapper.updateByPrimaryKeySelective(record);
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("databaseId",record.getDatabaseId());
        ZlDatabaseInfo keyInfo = databaseInfoMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        String cdskey = "dynamic-" + keyInfo.getDatabaseId();
        try{
            DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
            if(dynamicRoutingDataSource.getCurrentDataSources().containsKey(cdskey)){
                dynamicRoutingDataSource.removeDataSource(cdskey);
            }
        }catch(Exception e){
        }
        
        return res;
    }
    
    @Override
    public ResDatabaseInfoDelDTO deleteDatabaseInfoInfo(ReqDTO<ReqDatabaseInfoDelDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqDatabaseInfoDelDTO reqData = reqInfo.getReqData();
        ResDatabaseInfoDelDTO res = new ResDatabaseInfoDelDTO();
        Instant time = getSystemTime().getUtcTime();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqData);
        
        ZlDatabaseInfo keyInfo = databaseInfoMapper.selectOneByMap(paramMap);
        
        databaseInfoMapper.deleteByMap(paramMap);
        databaseSqlMapper.deleteByMap(paramMap);
        databaseTableMapper.deleteByMap(paramMap);
        
        String cdskey = "dynamic-" + keyInfo.getDatabaseId();
        try{
            DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
            if(dynamicRoutingDataSource.getCurrentDataSources().containsKey(cdskey)){
                dynamicRoutingDataSource.removeDataSource(cdskey);
            }
        }catch(Exception e){
        }
        
        return res;
    }
    
    @Override
    public ResDatabaseInfoStateDTO updateDatabaseInfoState(ReqDTO<ReqDatabaseInfoStateDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqDatabaseInfoStateDTO reqData = reqInfo.getReqData();
        ResDatabaseInfoStateDTO res = new ResDatabaseInfoStateDTO();
        Instant time = getSystemTime().getUtcTime();
         
        ZlDatabaseInfo record = new ZlDatabaseInfo();
        BeanUtil.copyProperties(reqData, record);
        initUpdateInfo(record, reqInfo, time);
        databaseInfoMapper.updateByPrimaryKeySelective(record);
         
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("databaseId",record.getDatabaseId());
        ZlDatabaseInfo keyInfo = databaseInfoMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ZlDatabaseInfo selectDatabaseInfo(String databaseId) throws Exception{
        // TODO Auto-generated method stub
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("databaseId", databaseId);
        ZlDatabaseInfo databaseInfo = databaseInfoMapper.selectOneByMap(paramMap);
        return databaseInfo;
    }
    
}